/**
 * @file data_structures_benchmark.cpp
 * @brief 高性能数据结构的基准测试
 * 
 * 这个文件包含对我们实现的优化数据结构与标准库容器的性能比较测试。
 * 测试包括：
 * 1. 环形缓冲区 vs std::deque/std::vector
 * 2. 对象池 vs 标准内存分配
 * 3. 无锁队列 vs 互斥锁保护的std::queue
 */

#include "utils/ring_buffer.h"
#include "utils/object_pool.h"
#include "utils/lockfree_queue.h"
#include <gtest/gtest.h>
#include <chrono>
#include <vector>
#include <deque>
#include <queue>
#include <memory>
#include <mutex>
#include <thread>
#include <functional>
#include <iostream>
#include <iomanip>
#include <sstream>

using namespace hft::utils;

// 用于测试的简单类
class BenchmarkObject {
public:
    BenchmarkObject() noexcept : value_(0) {}
    explicit BenchmarkObject(int v) noexcept : value_(v) {}
    void setValue(int v) noexcept { value_ = v; }
    int getValue() const noexcept { return value_; }
private:
    int value_;
    // 添加一些填充，使对象更大，以便更好地测量内存分配的影响
    char padding_[60] = {}; // 使对象大小为64字节（缓存行大小）
};

// 计时器辅助类
class Timer {
public:
    Timer(const std::string& name) : name_(name), start_(std::chrono::high_resolution_clock::now()) {}
    
    ~Timer() {
        auto end = std::chrono::high_resolution_clock::now();
        auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start_).count();
        std::cout << std::setw(30) << std::left << name_ << ": " 
                  << std::setw(10) << std::right << duration << " us" << std::endl;
    }
    
private:
    std::string name_;
    std::chrono::time_point<std::chrono::high_resolution_clock> start_;
};

// 格式化结果输出
void printResult(const std::string& test_name, double custom_time, double std_time) {
    double speedup = std_time / custom_time;
    std::cout << "=== " << test_name << " ===" << std::endl;
    std::cout << "Custom implementation: " << custom_time << " us" << std::endl;
    std::cout << "Standard library: " << std_time << " us" << std::endl;
    std::cout << "Speedup: " << std::fixed << std::setprecision(2) << speedup << "x" << std::endl;
    std::cout << std::endl;
}

// 环形缓冲区基准测试
TEST(DataStructuresBenchmark, RingBufferVsStdContainers) {
    constexpr size_t BUFFER_SIZE = 1024;
    constexpr size_t NUM_OPERATIONS = 10000000;
    
    std::cout << "\n=== RING BUFFER BENCHMARKS ===" << std::endl;
    
    // 测试1: 连续写入
    {
        double ring_buffer_time = 0;
        double vector_time = 0;
        double deque_time = 0;
        
        // 环形缓冲区
        {
            RingBuffer<int, BUFFER_SIZE> buffer;
            auto start = std::chrono::high_resolution_clock::now();
            
            for (size_t i = 0; i < NUM_OPERATIONS; ++i) {
                buffer.push_back(i);
            }
            
            auto end = std::chrono::high_resolution_clock::now();
            ring_buffer_time = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
            std::cout << "RingBuffer continuous write: " << ring_buffer_time << " us" << std::endl;
        }
        
        // std::vector (with reserve)
        {
            std::vector<int> vec;
            vec.reserve(BUFFER_SIZE);
            auto start = std::chrono::high_resolution_clock::now();
            
            for (size_t i = 0; i < NUM_OPERATIONS; ++i) {
                if (vec.size() >= BUFFER_SIZE) {
                    vec.erase(vec.begin());
                }
                vec.push_back(i);
            }
            
            auto end = std::chrono::high_resolution_clock::now();
            vector_time = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
            std::cout << "std::vector continuous write: " << vector_time << " us" << std::endl;
        }
        
        // std::deque
        {
            std::deque<int> deq;
            auto start = std::chrono::high_resolution_clock::now();
            
            for (size_t i = 0; i < NUM_OPERATIONS; ++i) {
                if (deq.size() >= BUFFER_SIZE) {
                    deq.pop_front();
                }
                deq.push_back(i);
            }
            
            auto end = std::chrono::high_resolution_clock::now();
            deque_time = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
            std::cout << "std::deque continuous write: " << deque_time << " us" << std::endl;
        }
        
        std::cout << "\nRingBuffer vs Vector speedup: " << std::fixed << std::setprecision(2) 
                  << vector_time / ring_buffer_time << "x" << std::endl;
        std::cout << "RingBuffer vs Deque speedup: " << std::fixed << std::setprecision(2) 
                  << deque_time / ring_buffer_time << "x" << std::endl;
    }
    
    // 测试2: 读写混合
    {
        std::cout << "\n--- Mixed Read/Write Operations ---" << std::endl;
        
        double ring_buffer_time = 0;
        double deque_time = 0;
        
        // 环形缓冲区
        {
            RingBuffer<int, BUFFER_SIZE> buffer;
            auto start = std::chrono::high_resolution_clock::now();
            
            for (size_t i = 0; i < NUM_OPERATIONS; ++i) {
                buffer.push_back(i);
                if (i % 10 == 0) {  // 每10次写入读取一次
                    volatile int val = buffer[i % buffer.size()];
                    (void)val;  // 防止编译器优化
                }
            }
            
            auto end = std::chrono::high_resolution_clock::now();
            ring_buffer_time = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
            std::cout << "RingBuffer mixed read/write: " << ring_buffer_time << " us" << std::endl;
        }
        
        // std::deque
        {
            std::deque<int> deq;
            auto start = std::chrono::high_resolution_clock::now();
            
            for (size_t i = 0; i < NUM_OPERATIONS; ++i) {
                if (deq.size() >= BUFFER_SIZE) {
                    deq.pop_front();
                }
                deq.push_back(i);
                if (i % 10 == 0) {  // 每10次写入读取一次
                    volatile int val = deq[i % deq.size()];
                    (void)val;  // 防止编译器优化
                }
            }
            
            auto end = std::chrono::high_resolution_clock::now();
            deque_time = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
            std::cout << "std::deque mixed read/write: " << deque_time << " us" << std::endl;
        }
        
        std::cout << "\nRingBuffer vs Deque speedup (mixed): " << std::fixed << std::setprecision(2) 
                  << deque_time / ring_buffer_time << "x" << std::endl;
    }
}

// 对象池基准测试
TEST(DataStructuresBenchmark, ObjectPoolVsStandardAllocation) {
    constexpr size_t POOL_SIZE = 1024;
    constexpr size_t NUM_OPERATIONS = 1000000;
    
    std::cout << "\n=== OBJECT POOL BENCHMARKS ===" << std::endl;
    
    // 测试1: 单线程分配/释放
    {
        double pool_time = 0;
        double new_delete_time = 0;
        double make_unique_time = 0;
        
        // 对象池
        {
            ObjectPool<BenchmarkObject, POOL_SIZE> pool;
            auto start = std::chrono::high_resolution_clock::now();
            
            for (size_t i = 0; i < NUM_OPERATIONS; ++i) {
                auto obj = pool.acquire();
                if (obj) {
                    obj.value()->setValue(i);
                    volatile int val = obj.value()->getValue();
                    (void)val;  // 防止编译器优化
                }
            }
            
            auto end = std::chrono::high_resolution_clock::now();
            pool_time = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
            std::cout << "ObjectPool allocation/deallocation: " << pool_time << " us" << std::endl;
        }
        
        // new/delete
        {
            auto start = std::chrono::high_resolution_clock::now();
            
            for (size_t i = 0; i < NUM_OPERATIONS; ++i) {
                auto obj = new BenchmarkObject();
                obj->setValue(i);
                volatile int val = obj->getValue();
                (void)val;  // 防止编译器优化
                delete obj;
            }
            
            auto end = std::chrono::high_resolution_clock::now();
            new_delete_time = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
            std::cout << "new/delete allocation/deallocation: " << new_delete_time << " us" << std::endl;
        }
        
        // std::make_unique
        {
            auto start = std::chrono::high_resolution_clock::now();
            
            for (size_t i = 0; i < NUM_OPERATIONS; ++i) {
                auto obj = std::make_unique<BenchmarkObject>();
                obj->setValue(i);
                volatile int val = obj->getValue();
                (void)val;  // 防止编译器优化
            }
            
            auto end = std::chrono::high_resolution_clock::now();
            make_unique_time = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
            std::cout << "std::make_unique allocation/deallocation: " << make_unique_time << " us" << std::endl;
        }
        
        std::cout << "\nObjectPool vs new/delete speedup: " << std::fixed << std::setprecision(2) 
                  << new_delete_time / pool_time << "x" << std::endl;
        std::cout << "ObjectPool vs std::make_unique speedup: " << std::fixed << std::setprecision(2) 
                  << make_unique_time / pool_time << "x" << std::endl;
    }
    
    // 测试2: 多线程分配/释放
    {
        std::cout << "\n--- Multi-threaded Allocation/Deallocation ---" << std::endl;
        constexpr size_t NUM_THREADS = 4;
        constexpr size_t OPS_PER_THREAD = NUM_OPERATIONS / NUM_THREADS;
        
        double pool_time = 0;
        double make_unique_time = 0;
        
        // 对象池
        {
            ObjectPool<BenchmarkObject, POOL_SIZE> pool;
            auto start = std::chrono::high_resolution_clock::now();
            
            std::vector<std::thread> threads;
            for (size_t t = 0; t < NUM_THREADS; ++t) {
                threads.emplace_back([&pool, t]() {
                    for (size_t i = 0; i < OPS_PER_THREAD; ++i) {
                        auto obj = pool.acquire();
                        if (obj) {
                            obj.value()->setValue(i);
                            volatile int val = obj.value()->getValue();
                            (void)val;  // 防止编译器优化
                        }
                    }
                });
            }
            
            for (auto& thread : threads) {
                thread.join();
            }
            
            auto end = std::chrono::high_resolution_clock::now();
            pool_time = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
            std::cout << "ObjectPool multi-threaded: " << pool_time << " us" << std::endl;
        }
        
        // std::make_unique
        {
            auto start = std::chrono::high_resolution_clock::now();
            
            std::vector<std::thread> threads;
            for (size_t t = 0; t < NUM_THREADS; ++t) {
                threads.emplace_back([]() {
                    for (size_t i = 0; i < OPS_PER_THREAD; ++i) {
                        auto obj = std::make_unique<BenchmarkObject>();
                        obj->setValue(i);
                        volatile int val = obj->getValue();
                        (void)val;  // 防止编译器优化
                    }
                });
            }
            
            for (auto& thread : threads) {
                thread.join();
            }
            
            auto end = std::chrono::high_resolution_clock::now();
            make_unique_time = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
            std::cout << "std::make_unique multi-threaded: " << make_unique_time << " us" << std::endl;
        }
        
        std::cout << "\nObjectPool vs std::make_unique speedup (multi-threaded): " << std::fixed << std::setprecision(2) 
                  << make_unique_time / pool_time << "x" << std::endl;
    }
}

// 无锁队列基准测试
TEST(DataStructuresBenchmark, LockfreeQueueVsMutexQueue) {
    constexpr size_t QUEUE_SIZE = 1024;
    constexpr size_t NUM_OPERATIONS = 1000000;
    
    std::cout << "\n=== LOCKFREE QUEUE BENCHMARKS ===" << std::endl;
    
    // 测试1: SPSC (单生产者单消费者) 场景
    {
        double lockfree_time = 0;
        double mutex_time = 0;
        
        // 无锁队列
        {
            LockfreeQueue<int, QUEUE_SIZE> queue;
            std::atomic<bool> producer_finished{false};
            
            auto start = std::chrono::high_resolution_clock::now();
            
            std::thread producer([&]() {
                for (size_t i = 0; i < NUM_OPERATIONS; ++i) {
                    while (!queue.try_push(i)) {
                        std::this_thread::yield();
                    }
                }
                producer_finished = true;
            });
            
            std::thread consumer([&]() {
                int value;
                size_t count = 0;
                while (count < NUM_OPERATIONS) {
                    if (queue.try_pop(value)) {
                        count++;
                    } else if (!producer_finished) {
                        std::this_thread::yield();
                    }
                }
            });
            
            producer.join();
            consumer.join();
            
            auto end = std::chrono::high_resolution_clock::now();
            lockfree_time = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
            std::cout << "Lockfree queue SPSC: " << lockfree_time << " us" << std::endl;
        }
        
        // 互斥锁保护的队列
        {
            std::queue<int> queue;
            std::mutex mutex;
            std::atomic<bool> producer_finished{false};
            
            auto start = std::chrono::high_resolution_clock::now();
            
            std::thread producer([&]() {
                for (size_t i = 0; i < NUM_OPERATIONS; ++i) {
                    {
                        std::lock_guard<std::mutex> lock(mutex);
                        queue.push(i);
                    }
                }
                producer_finished = true;
            });
            
            std::thread consumer([&]() {
                int value;
                size_t count = 0;
                while (count < NUM_OPERATIONS) {
                    bool got_value = false;
                    {
                        std::lock_guard<std::mutex> lock(mutex);
                        if (!queue.empty()) {
                            value = queue.front();
                            queue.pop();
                            got_value = true;
                        }
                    }
                    
                    if (got_value) {
                        count++;
                    } else if (!producer_finished) {
                        std::this_thread::yield();
                    }
                }
            });
            
            producer.join();
            consumer.join();
            
            auto end = std::chrono::high_resolution_clock::now();
            mutex_time = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
            std::cout << "Mutex-based queue SPSC: " << mutex_time << " us" << std::endl;
        }
        
        std::cout << "\nLockfree vs Mutex-based queue speedup: " << std::fixed << std::setprecision(2) 
                  << mutex_time / lockfree_time << "x" << std::endl;
    }
    
    // 测试2: 高负载场景
    {
        std::cout << "\n--- High Contention Scenario ---" << std::endl;
        constexpr size_t BURST_SIZE = 100;  // 每次突发操作的数量
        
        double lockfree_time = 0;
        double mutex_time = 0;
        
        // 无锁队列
        {
            LockfreeQueue<int, QUEUE_SIZE> queue;
            std::atomic<bool> producer_finished{false};
            
            auto start = std::chrono::high_resolution_clock::now();
            
            std::thread producer([&]() {
                for (size_t i = 0; i < NUM_OPERATIONS; ++i) {
                    // 突发写入
                    if (i % BURST_SIZE == 0) {
                        for (size_t j = 0; j < BURST_SIZE && i + j < NUM_OPERATIONS; ++j) {
                            while (!queue.try_push(i + j)) {
                                std::this_thread::yield();
                            }
                        }
                        i += BURST_SIZE - 1;  // -1 因为循环会再加1
                    } else {
                        while (!queue.try_push(i)) {
                            std::this_thread::yield();
                        }
                    }
                }
                producer_finished = true;
            });
            
            std::thread consumer([&]() {
                int value;
                size_t count = 0;
                while (count < NUM_OPERATIONS) {
                    // 突发读取
                    if (count % BURST_SIZE == 0) {
                        for (size_t j = 0; j < BURST_SIZE && count + j < NUM_OPERATIONS; ++j) {
                            while (!queue.try_pop(value) && (!producer_finished || !queue.empty())) {
                                std::this_thread::yield();
                            }
                            if (queue.try_pop(value)) {
                                count++;
                            } else {
                                break;
                            }
                        }
                    } else {
                        if (queue.try_pop(value)) {
                            count++;
                        } else if (!producer_finished || !queue.empty()) {
                            std::this_thread::yield();
                        }
                    }
                }
            });
            
            producer.join();
            consumer.join();
            
            auto end = std::chrono::high_resolution_clock::now();
            lockfree_time = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
            std::cout << "Lockfree queue high contention: " << lockfree_time << " us" << std::endl;
        }
        
        // 互斥锁保护的队列
        {
            std::queue<int> queue;
            std::mutex mutex;
            std::atomic<bool> producer_finished{false};
            
            auto start = std::chrono::high_resolution_clock::now();
            
            std::thread producer([&]() {
                for (size_t i = 0; i < NUM_OPERATIONS; ++i) {
                    // 突发写入
                    if (i % BURST_SIZE == 0) {
                        std::lock_guard<std::mutex> lock(mutex);
                        for (size_t j = 0; j < BURST_SIZE && i + j < NUM_OPERATIONS; ++j) {
                            queue.push(i + j);
                        }
                        i += BURST_SIZE - 1;  // -1 因为循环会再加1
                    } else {
                        std::lock_guard<std::mutex> lock(mutex);
                        queue.push(i);
                    }
                }
                producer_finished = true;
            });
            
            std::thread consumer([&]() {
                size_t count = 0;
                while (count < NUM_OPERATIONS) {
                    // 突发读取
                    if (count % BURST_SIZE == 0) {
                        std::lock_guard<std::mutex> lock(mutex);
                        for (size_t j = 0; j < BURST_SIZE && count + j < NUM_OPERATIONS && !queue.empty(); ++j) {
                            queue.pop();
                            count++;
                        }
                    } else {
                        std::lock_guard<std::mutex> lock(mutex);
                        if (!queue.empty()) {
                            queue.pop();
                            count++;
                        }
                    }
                    
                    if (count < NUM_OPERATIONS && queue.empty() && !producer_finished) {
                        std::this_thread::yield();
                    }
                }
            });
            
            producer.join();
            consumer.join();
            
            auto end = std::chrono::high_resolution_clock::now();
            mutex_time = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
            std::cout << "Mutex-based queue high contention: " << mutex_time << " us" << std::endl;
        }
        
        std::cout << "\nLockfree vs Mutex-based queue speedup (high contention): " << std::fixed << std::setprecision(2) 
                  << mutex_time / lockfree_time << "x" << std::endl;
    }
}